package com.chwl.framework.grpc;

import com.chwl.framework.grpc.discover.ServiceDiscoverService;
import com.chwl.framework.grpc.service.GrpcCommonService;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Optional;

/**
 * GRPC Server 启动器
 */
public class GrpcServerRunner {

    private static final Logger log = LoggerFactory.getLogger(GrpcServerRunner.class.getName());

    private final ServerBuilder<?> serverBuilder;

    private final GrpcCommonService commonService;

    private Server server;

    /**
     * 包含服务注册发现业务
     *
     * @param port
     * @param commonService
     */
    public GrpcServerRunner(int port, GrpcCommonService commonService) {
        this.serverBuilder = ServerBuilder.forPort(port);
        this.commonService = commonService;
        //包含服务注册发现业务
        ServiceDiscoverService.getInstance().heartbeat(port, new ArrayList<>(commonService.getServiceNames()));
    }


    public void start() throws Exception {
        server = serverBuilder.addService(commonService).build().start();
        if (log.isInfoEnabled()) {
            log.info("GRPC Server started, listening on port:{} ", server.getPort());
        }
        startDaemonAwaitThread();
    }

    public void destroy() {
        //先将服务在etcd下线 再关闭服务
        ServiceDiscoverService.getInstance().destroy();
        Optional.ofNullable(server).ifPresent(Server::shutdown);
        if (log.isInfoEnabled()) {
            log.info("GRPC server stopped.");
        }
    }

    private void startDaemonAwaitThread() {
        Thread awaitThread = new Thread(() -> {
            try {
                GrpcServerRunner.this.server.awaitTermination();
            } catch (InterruptedException e) {
                if (log.isInfoEnabled()) {
                    log.info("GRPC server stopped fail,error message:{}", e.getMessage(), e);
                }
            }
        });
        awaitThread.setDaemon(false);
        awaitThread.start();
    }
}
